package top.wardyan.wtask.ctrl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import com.jfinal.aop.Inject;
import com.jfinal.core.Path;
import com.jfinal.kit.Prop;
import com.jfinal.plugin.activerecord.Record;

import cn.hutool.core.lang.Console;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import top.wardyan.base.common.config.ConfigProp;
import top.wardyan.base.common.util.DateUtil;
import top.wardyan.common.ctrl.BaseController;
import top.wardyan.wtask.feishu.api.FeishuMsgBusiness;
import top.wardyan.wtask.jobs.FeishuCheckJob;
import top.wardyan.wtask.jobs.TapdDownloadJob;
import top.wardyan.wtask.service.IProcService;
import top.wardyan.wtask.tapd.api.TapdBusiness;
import top.wardyan.wtask.tapd.util.WorkHourUtil;

@Path("/task")
public class TaskCtrl extends BaseController{

	private static final cn.hutool.log.Log log = cn.hutool.log.Log.get();
	private static final Prop PROP = ConfigProp.load();
	private static final String FEISHUCHATID = PROP.get("feishu.chatid");

	@Inject FeishuMsgBusiness feishuBusiness;
	@Inject TapdBusiness tapdBusiness;
	@Inject IProcService procService;
	@Inject FeishuCheckJob checkJob;
	@Inject TapdDownloadJob tapdDownloadJob;
	
	/**
	 * 从飞书拉取
	 * man:当前人
	 */
	public void feishu(Timestamp begin, Boolean force, String man) {
		
		Integer cnt = 0;
		
		if(begin == null) {
			feishuBusiness.spy();
		}else {
			cnt = feishuBusiness.spy(begin, force, null);
		}
		
		this.home(man, DateUtil.range(1), null);
	}
	
	/**
	 * 从TAPD拉取需求和任务
	 */
	public void tapd(Timestamp begin, Timestamp end, String man) {
		if(begin == null) {
			// 如果没有给开始时间就拉取最近两天的
			begin = DateUtil.range(19);
		}
		if(end == null) {
			end = DateUtil.getCurrentTimestamp();
		}
		tapdBusiness.fetchStory(begin, end);
		tapdBusiness.fetchTask(begin, end);
		this.home(man, DateUtil.range(1), null);
	}
	
	/**
	 * 从TAPD拉取需求
	 */
	public void tapdstory(Timestamp begin, Timestamp end, String man) {
		if(begin == null) {
			// 如果没有给开始时间就拉取最近一个星期的
			begin = DateUtil.range(19);
		}
		if(end == null) {
			end = DateUtil.getCurrentTimestamp();
		}
		tapdBusiness.fetchStory(begin, end);
		Integer second = RandomUtil.randomInt(5, 20);
        while(second > 0) {
        	Console.log("暂停一会,假装是个人在操作...等待时间秒:{}");
         	ThreadUtil.sleep(1000);
         	second -= 1;
        }
		tapdBusiness.fetchTask(begin, end);
		this.home(man, DateUtil.range(1), null);
	}
	
	/**
	 * 从TAPD拉取任务
	 */
	public void tapdtask(Timestamp begin, Timestamp end, String man) {
		if(begin == null) {
			// 如果没有给开始时间就拉取最近一个星期的
			begin = DateUtil.range(17);
		}
		if(end == null) {
			end = DateUtil.getCurrentTimestamp();
		}
		tapdBusiness.fetchTask(begin, end);
		this.home(man, DateUtil.range(1), null);
	}
	
//	/**
//	 * 显示首页统计及明细
//	 */
//	public void home(String man, Timestamp date) {
//		// 显示内容:指定人或全部人的统计
//		// 指定日期的任务情况
//		// 飞书:
//		// 本周完成工时统计
//		
//		// 上周完成工时统计
//		// TAPD:
//		// 本周完成工时统计
//		// 上周完成工时统计
//		// 过去一个月每天完成工时统计
//		// 本周完成任务列表
//		// 上周完成任务列表
//		// 未完成紧急任务
//		// 绩效统计
//		// 检查:任务完成,需求未标记完成的
//		
//		if(date == null) {
//			date = DateUtil.range(1);
//		}
////		List<Record> tapddates = procService.yp_tapd_date(man, date);
////		Float totalhour = 0.0F;
////		for(Record r : tapddates) {
////			totalhour += r.getFloat("xHour");
////		}
////		String th = NumberUtil.decimalFormat("0.#", totalhour);
////		// this.renderJson(tapddates);
////		this.set("tapddates", tapddates);
////		this.set("date", DateUtil.format(date, "yyyy年MM月dd日"));
////		this.set("man", man);
////		this.set("totalhour", th);
////		this.set("week", DateUtil.format(date, "EEEE"));
////		this.renderTemplate("home.html");
//		
//		String html = procService.yp_tapd_mail(man, date);
//		
//		this.renderHtml(html);
//	}

	private void hometoday(String man, Timestamp date) {
		// 显示内容:指定人或全部人的统计
		// 指定日期的任务情况
		// 飞书:
		// 本周完成工时统计
		
		// 上周完成工时统计
		// TAPD:
		// 本周完成工时统计
		// 上周完成工时统计
		// 过去一个月每天完成工时统计
		// 本周完成任务列表
		// 上周完成任务列表
		// 未完成紧急任务
		// 绩效统计
		// 检查:任务完成,需求未标记完成的
		
		if(date == null) {
			date = DateUtil.range(1);
		}
		List<Record> tapddates = procService.yp_tapd_date(man, date);
		Float totalhour = 0.0F;
		for(Record r : tapddates) {
			if(r.getStr("xHour") != null) {
				totalhour += r.getFloat("xHour");
			}
		}
		String th = NumberUtil.decimalFormat("0.#", totalhour);
		// this.renderJson(tapddates);
		this.set("tapddates", tapddates);
		this.set("date", DateUtil.format(date, "yyyy年MM月dd日"));
		this.set("man", man);
		this.set("totalhour", th);
		this.set("week", DateUtil.format(date, "EEEE"));
				
	}
	/**
	 * 飞书本周 // 要分人 // 不,全部人的另外搞
	 * @param man
	 * @param date
	 */
	private void homefeishucurrentweek(String man, Timestamp date) {
		List<Record> datas = procService.yp_query_feishu_week(man, date);
		Float totalhour = 0.0F;
		for(Record r : datas) {
			if(r.getStr("xHour") != null) {
				totalhour += r.getFloat("xHour");
			}
		}
		String th = NumberUtil.decimalFormat("0.#", totalhour);
		// this.renderJson(tapddates);
		this.set("feishu_currentweek_datas", datas);
		Float expecthour = WorkHourUtil.calWeekWorkHour(date);
		// 本周应产出工时
		this.set("feishu_currentweek_expecthour", NumberUtil.decimalFormat("0.#", expecthour));
		// 本周工时统计
		this.set("feishu_currentweek_acturalhour", th);
		// 预计效率
		Float rate = 0.0F;
		if(expecthour > 0) {
			rate = totalhour * 100.0F / expecthour;
		}
		this.set("feishu_currentweek_effect",  NumberUtil.decimalFormat("0.#", rate) + "%");
	}

	/**
	 * 飞书上周
	 * @param man
	 * @param date
	 */
	private void homefeishupreweek(String man, Timestamp date) {
		date = new Timestamp(date.getTime() - 1000 * 60 * 60 * 24 * 7L);
		List<Record> datas = procService.yp_query_feishu_week(man, date);
		Float totalhour = 0.0F;
		for(Record r : datas) {
			if(r.getStr("xHour") != null) {
				totalhour += r.getFloat("xHour");
			}
		}
		String th = NumberUtil.decimalFormat("0.#", totalhour);
		// this.renderJson(tapddates);
		this.set("feishu_preweek_datas", datas);
		
		// 本周应产出工时
		//this.set("feishu_preweek_expecthour", 0.0);
		// 本周工时统计
		this.set("feishu_preweek_acturalhour", th);
		// 预计效率
		//this.set("feishu_preweek_effect", 0.0);
	}

	/**
	 * TAPD本周
	 * @param man
	 * @param date
	 */
	private void hometapdcurrentweek(String man, Timestamp date) {
		//date = new Timestamp(date.getTime() - 1000 * 60 * 60 * 24 * 7L);
		List<Record> datas = procService.yp_query_tapd_week(man, date);
		Float totalhour = 0.0F;
		for(Record r : datas) {
			if(r.getStr("xHour") != null) {
				totalhour += r.getFloat("xHour");
			}
		}
		String th = NumberUtil.decimalFormat("0.#", totalhour);
		// this.renderJson(tapddates);
		this.set("tapd_currentweek_datas", datas);
		Float expecthour = WorkHourUtil.calWeekWorkHour(date);
		// 本周应产出工时
		this.set("tapd_currentweek_expecthour", NumberUtil.decimalFormat("0.#", expecthour));
		// 本周工时统计
		this.set("tapd_currentweek_acturalhour", th);
		// 预计效率
		Float rate = 0.0F;
		if(expecthour > 0) {
			rate = totalhour * 100.0F / expecthour;
		}
		// 预计效率
		this.set("tapd_currentweek_effect", NumberUtil.decimalFormat("0.#", rate) + "%");
	}

	/**
	 * TAPD上周
	 * @param man
	 * @param date
	 */
	private void hometapdpreweek(String man, Timestamp date) {
		date = new Timestamp(date.getTime() - 1000 * 60 * 60 * 24 * 7L);
		List<Record> datas = procService.yp_query_tapd_week(man, date);
		Float totalhour = 0.0F;
		for(Record r : datas) {
			if(r.getStr("xHour") != null) {
				totalhour += r.getFloat("xHour");
			}
		}
		String th = NumberUtil.decimalFormat("0.#", totalhour);
		// this.renderJson(tapddates);
		this.set("tapd_preweek_datas", datas);
		
		// 本周应产出工时
		//this.set("feishu_preweek_expecthour", 0.0);
		// 本周工时统计
		this.set("tapd_preweek_acturalhour", th);
		// 预计效率
		//this.set("feishu_preweek_effect", 0.0);
	}
	
	
	
	
	


	/**
	 * TAPD过去一个月
	 * @param man
	 * @param date
	 */
	private void hometapdcurrentmonth(String man, Timestamp date) {
		//date = new Timestamp(date.getTime() - 1000 * 60 * 60 * 24 * 7L);
		List<Record> datas = procService.yp_query_tapd_month(man, date);
		Float totalhour = 0.0F;
		for(Record r : datas) {
			if(r.getStr("xHour") != null) {
				totalhour += r.getFloat("xHour");
			}
		}
		String th = NumberUtil.decimalFormat("0.#", totalhour);
		// this.renderJson(tapddates);
		this.set("tapd_currentmonth_datas", datas);
		Float expecthour = WorkHourUtil.calWeekWorkHour(date);
		// 本周应产出工时
		// TODO 月应产出工时
		this.set("tapd_currentmonth_expecthour", NumberUtil.decimalFormat("0.#", expecthour));
		// 本周工时统计
		this.set("tapd_currentmonth_acturalhour", th);
		// 预计效率
		Float rate = 0.0F;
		if(expecthour > 0) {
			rate = totalhour * 100.0F / expecthour;
		}
		// 预计效率
		this.set("tapd_currentmonth_effect", NumberUtil.decimalFormat("0.#", rate) + "%");
	}


	/**
	 * TAPD本周任务
	 * @param man
	 * @param date
	 */
	private void hometapdcurrentweektask(String man, Timestamp date) {
		//date = new Timestamp(date.getTime() - 1000 * 60 * 60 * 24 * 7L);
		List<Record> datas = procService.yp_query_tapd_weektask(man, date);
		this.set("tapd_currentweektask_datas", datas);
		this.set("tapd_currentweektask_datasize", datas.size());
	}


	/**
	 * TAPD上周任务
	 * @param man
	 * @param date
	 */
	private void hometapdpreweektask(String man, Timestamp date) {
		date = new Timestamp(date.getTime() - 1000 * 60 * 60 * 24 * 7L);
		List<Record> datas = procService.yp_query_tapd_weektask(man, date);
		this.set("tapd_preweektask_datas", datas);
		this.set("tapd_preweektask_datasize", datas.size());
	}


	/**
	 * 紧急任务/准备完成任务
	 * @param man
	 * @param date
	 */
	private void hometapdemergencytask(String man, Timestamp date) {
		List<Record> datas = procService.yp_query_tapd_weekemergency(man, date);
		this.set("tapd_emergency_datas", datas);
		this.set("tapd_emergency_datasize", datas.size());
	}
	
	

	private void hometapdprocessing(String man, Timestamp date) {
		List<Record> datas = procService.yp_query_progressing(man, date);
		this.set("tapd_processing_datas", datas);
		this.set("tapd_processing_datasize", datas.size());
	}

	private void hometapdstoryprocessing(String man, Timestamp date) {
		List<Record> datas = procService.yp_query_storyprogressing(man, date);
		this.set("tapd_storyprocessing_datas", datas);
		this.set("tapd_storyprocessing_datasize", datas.size());
	}

	private void hometapdperformance(String man, Timestamp date) {
		List<Record> datas = procService.yp_query_performance(man, date);
		this.set("tapd_performance_datas", datas);
		this.set("tapd_performance_datasize", datas.size());
	}

	
	
	
	
	
	/**
	 * 显示首页统计及明细
	 */
	public void home(String man, Timestamp date, Timestamp currentdate) {
		if(currentdate != null) {
			date = currentdate;
		}
		if(date == null) {
			date = DateUtil.range(1);
		}
		
		
		// 未完成任务
		this.hometapdprocessing(man, date);
		// 未完成需求
		this.hometapdstoryprocessing(man, date);
		// 绩效
		this.hometapdperformance(man, date);
		
		// 当天任务统计
		this.hometoday(man, date);
		
		// 飞书本周工时记录
		this.homefeishucurrentweek(man, date);
		// 飞书上周工时记录
		this.homefeishupreweek(man, date);
		

		
		// TAPD本周工时记录
		this.hometapdcurrentweek(man, date);
		// TAPD上周工时记录
		this.hometapdpreweek(man, date);
		
		// TAPD过去一个月
		this.hometapdcurrentmonth(man, date);
		
		// TAPD本周任务
		this.hometapdcurrentweektask(man, date);

		// TAPD上周任务
		this.hometapdpreweektask(man, date);

		// TAPD未完成任务
		this.hometapdemergencytask(man, date);
		
		this.set("date", date);
		this.set("man", man);
		List<Record> es = procService.yp_listempls(false);
		List<String> mans = es.stream().map(new Function<Record,String>(){

			@Override
			public String apply(Record t) {
				return t.getStr("xName");
			}
			
		}).distinct().sorted(new Comparator<String>() {

			@Override
			public int compare(String a, String b) {
				// return StrUtil.compare(a, b, true);
				return PinyinUtil.getPinyin(a).compareTo(PinyinUtil.getPinyin(b));
			}
			
		}).collect(Collectors.toList());
		this.set("mans", mans);
		
		// 飞书和TAPD最后刷新时间
		this.set("importingstatus", procService.yp_qry_preimporttime());
		
		this.set("feishulist", procService.yp_query_feishu_list(date, man));
		
		
		
		
		
		// 
		Timestamp today = DateUtil.range(1);
		Timestamp yestoday = DateUtil.range(19);
		Timestamp date3 = new Timestamp(today.getTime() - 1000 * 60 * 60 * 24 * 2);
		Timestamp date4 = new Timestamp(today.getTime() - 1000 * 60 * 60 * 24 * 3);
		Timestamp date5 = new Timestamp(today.getTime() - 1000 * 60 * 60 * 24 * 4);
		Timestamp date6 = new Timestamp(today.getTime() - 1000 * 60 * 60 * 24 * 5);
		Timestamp date7 = new Timestamp(today.getTime() - 1000 * 60 * 60 * 24 * 6);
		List<Timestamp> currentdates = new ArrayList<>();

		currentdates.add(today);
		currentdates.add(yestoday);
		currentdates.add(date3);
		currentdates.add(date4);
		currentdates.add(date5);
		currentdates.add(date6);
		currentdates.add(date7);
		this.set("currentdates", currentdates);
		
		
		this.renderTemplate("home.html");
	}
	
	
	/**
	 * 周统计
	 * @param date
	 */
	public void weeksummary(Timestamp date, Float totalHour) {
		if(date == null) {
			date = DateUtil.range(1);
		}
		List<Record> rs = procService.yp_qry_weeksummary(date);
		this.set("datas", rs);
		
		// 还要把人和日期列出来
		List<Record> empls = procService.yp_listempls(true);
//		List<String> mans = empls.stream().map(new Function<Record,String>(){
//			@Override
//			public String apply(Record t) {
//				return t.getStr("xName");
//			}
//		}).distinct().sorted(new Comparator<String>() {
//
//			@Override
//			public int compare(String a, String b) {
//				// return StrUtil.compare(a, b, true);
//				return PinyinUtil.getPinyin(a).compareTo(PinyinUtil.getPinyin(b));
//			}
//			
//		}).collect(Collectors.toList());
		
		empls = empls.stream().filter(new Predicate<Record>() {

			@Override
			public boolean test(Record t) {
				Boolean ok = (t.get("xCountRate") != null && t.getFloat("xCountRate") > 0.0F)
						|| t.getBoolean("xIsCount")|| t.getBoolean("xIsCountTapd")
						;
//				rs.stream().map(new Function<Record, Boolean>(){
//
//					@Override
//					public Boolean apply(Record t) {
//						Boolean r = false;
////						r = (t.getFloat("xFeishuTotalHour") != null && t.getFloat("xFeishuTotalHour") > 0.0F)
////								|| t.getFloat("xTapdHTotalHour") != null && t.getFloat("xTapdHTotalHour") > 0.0F 
////								;
//						r = 
//						return r;
//					}
//					
//				});
				return ok;
			}
			
		}).collect(Collectors.toList());
		
		this.set("mans", empls);
		

		List<Timestamp> dates = rs.stream().map(new Function<Record,Timestamp>(){
			@Override
			public Timestamp apply(Record t) {
				return t.getTimestamp("xDate");
			}
		}).distinct().sorted(new Comparator<Timestamp>() {

			@Override
			public int compare(Timestamp a, Timestamp b) {
				return Long.compare(a.getTime(), b.getTime());
			}
			
		}).collect(Collectors.toList());
		
		this.set("dates", dates);
		
		if(totalHour == null || totalHour <= 0.0) {
			totalHour = rs.stream().map(new Function<Record, Float>(){

				@Override
				public Float apply(Record t) {
					return t.getFloat("xWeekTotalHour");
				}
				
			}).findFirst().get();
		}
		this.set("totalHour", totalHour);
		this.set("date", date);
		
		
		// 任务清单
		List<Record> weekalltasks = procService.yp_task_qryweekalltask(date, date);
		List<Record> weektaskstatistics =  procService.yp_task_qryweekstatistics(date, date);
		List<Record> groups = procService.yp_listgroups();
		this.set("weekalltasks", weekalltasks);
		this.set("weektaskstatistics", weektaskstatistics);
		this.set("groups", groups);
		
		
		List<Record> emergencys = procService.yp_query_tapd_emergencys();
		this.set("emergencys", emergencys);		
		
		

		// 总-客户工时统计
		// 分开发-客户工时共计
		// 总-客户本周紧急任务工时统计
		// 分开发-客户本周紧急任务工时共计
		List<Record> totalcusthours = procService.yp_listhoursbycust(date, date, 1);
		List<Record> devcusthours = procService.yp_listhoursbycust(date, date, 2);
		List<Record> totalemergencycusthours = procService.yp_listhoursbycust(date, date, 3);
		List<Record> devemergencycusthours = procService.yp_listhoursbycust(date, date, 4);

		this.set("totalcusthours", totalcusthours);
		this.set("devcusthours", devcusthours);
		this.set("totalemergencycusthours", totalemergencycusthours);
		this.set("devemergencycusthours", devemergencycusthours);
		// this.set("mans", mans);
		
		this.renderTemplate("weeksummary.html");
	}
	
	
	public void check(Timestamp date, Integer min, Boolean force) {
		if(date == null) {
			date = DateUtil.range(19);
		}
		if(min == null) {
			min = 1;
		}
		if(force == null) {
			force = false;
		}
		checkJob.deal(date, min, force);
		this.home("", date, null);
	}
	
	
	/**
	 * 把消息转发到飞书
	 */
	public void send(String man, Timestamp date, String msg) {
		if(man == null) {
			man = "";
		}
		if(msg == null) {
			msg = "";
		}
//		msg = msg.replace("<br>", System.lineSeparator());
//		msg = msg.replace("<br/>", System.lineSeparator());

		msg = msg.replace("<br>", "");
		msg = msg.replace("<br/>", "");
		String code = FEISHUCHATID;
		if(code != null && code.length() > 0) {

			try {
				// feishuBusiness.send("oc_e543d556315c4e770b1e7dbe02337abb", msg);
				feishuBusiness.send("chat_id", code, msg);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.renderText("OK");
		// this.redirect("/task/home?man=" + man);
		//this.home(man, date);
	}
	
	public void weekalert(String man) {
		checkJob.weekcheck(man);
		this.renderNull();
	}
	
	public void reimportmonth() {
		
	}
	
}
